package com.huaxin.hxmoduleworkorder.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.hxmoduleworkorder.common.enums.CustomerType;
import com.huaxin.hxmoduleworkorder.common.enums.InspectionOrderItemResultStatus;
import com.huaxin.hxmoduleworkorder.common.enums.InspectionOrderStatus;
import com.huaxin.hxmoduleworkorder.dto.ResponseCode;
import com.huaxin.hxmoduleworkorder.dto.ResponseResult;
import com.huaxin.hxmoduleworkorder.dto.request.InspectionOrderItemCreateReqDTO;
import com.huaxin.hxmoduleworkorder.dto.request.InspectionOrderItemExistReqDTO;
import com.huaxin.hxmoduleworkorder.dto.request.InspectionOrderItemUpdateReqDTO;
import com.huaxin.hxmoduleworkorder.event.InspectionOrderItemChangeEvent;
import com.huaxin.hxmoduleworkorder.mapper.InspectionOrderItemMapper;
import com.huaxin.hxmoduleworkorder.mapper.InspectionOrderMapper;
import com.huaxin.hxmoduleworkorder.mapping.InspectionOrderItemMapping;
import com.huaxin.hxmoduleworkorder.models.InspectionOrder;
import com.huaxin.hxmoduleworkorder.models.InspectionOrderItem;
import com.huaxin.hxmoduleworkorder.service.InspectionOrderItemService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

import static org.springframework.util.StringUtils.hasText;

/**
 * 巡查项服务实现类（使用 MapStruct 映射）
 *
 * @author fuai
 * @since 2025-09-02
 */
@Service
@RequiredArgsConstructor
public class InspectionOrderItemServiceImpl extends ServiceImpl<InspectionOrderItemMapper, InspectionOrderItem> implements InspectionOrderItemService {
    private final ApplicationContext applicationContext;
    private final InspectionOrderItemMapping mapping;
    private final ApplicationEventPublisher eventPublisher;
    private final InspectionOrderMapper inspectionOrderMapper;

    /**
     * 批量创建巡查项，并更新工单状态
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResponseResult<String> batchCreate(List<InspectionOrderItemCreateReqDTO> in) {
        // 1. 参数校验
        if (in == null || in.isEmpty()) {
            return ResponseResult.parameterError(null, "批量创建的巡查项列表不能为空");
        }

        String orderId = in.get(0).getInspectionOrderId();

        // 2. 查询工单
        InspectionOrder order = inspectionOrderMapper.selectById(orderId);
        if (order == null) {
            return ResponseResult.notFound(null, "该工单不存在");
        }

        // 3. 判断工单状态：只要有 PENDING 或 standardValue 为空，就表示“执行中”
        boolean hasIncomplete = in.stream().anyMatch(dto ->
                InspectionOrderItemResultStatus.PENDING.equals(dto.getResultStatus()) ||
                        (dto.getStandardValue() == null || dto.getStandardValue().trim().isEmpty())
        );

        InspectionOrderStatus newStatus = hasIncomplete
                ? InspectionOrderStatus.IN_PROGRESS
                : InspectionOrderStatus.COMPLETED;

        // 4. 更新工单状态
        order.setStatus(newStatus);
        inspectionOrderMapper.updateById(order);

        // 5. 转换并保存巡查项
        List<InspectionOrderItem> entityList = mapping.toEntityList(in);
        boolean saved = this.saveBatch(entityList);

        if (!saved) {
            throw new RuntimeException("批量保存巡查项失败");
        }

        // 6. 发布事件（确保在事务成功提交后发布）
        InspectionOrderItem item = entityList.get(0);
        eventPublisher.publishEvent(
                InspectionOrderItemChangeEvent.created(item.getInspectionOrderId(), item.getCabinetId())
        );

        return ResponseResult.ok("添加成功！");
    }

    @Override
    public ResponseResult<String> batchUpdate(List<InspectionOrderItemUpdateReqDTO> in) {
        if (in == null || in.isEmpty()) {
            return ResponseResult.parameterError(null, "批量更新的巡查项列表不能为空");
        }
        List<InspectionOrderItem> entityList = mapping.updateEntityList(in);
        if (this.updateBatchById(entityList)) {
            InspectionOrderItem item = entityList.get(0);
            eventPublisher.publishEvent(
                    InspectionOrderItemChangeEvent.updated(item.getInspectionOrderId(), item.getCabinetId())
            );
            return ResponseResult.ok("更新成功！");
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "更新失败，请稍后重试", null);
    }

    @Override
    public ResponseResult<InspectionOrderItem> getByItemId(String id) {
        if (StringUtils.isBlank(id)) {
            return ResponseResult.parameterError(null, "巡查项ID不能为空");
        }
        InspectionOrderItem entity = this.getById(id);
        if (entity == null) {
            return ResponseResult.notFound(null, "该巡查项不存在");
        }
        return ResponseResult.ok(entity);
    }

    @Override
    public ResponseResult<List<InspectionOrderItem>> listByOrder(String orderId, String customerId, String cabinetId) {
        if (StringUtils.isBlank(orderId)) {
            return ResponseResult.parameterError(null, "工单ID不能为空");
        }
        LambdaQueryWrapper<InspectionOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InspectionOrderItem::getInspectionOrderId, orderId);
        if (hasText(customerId)) {
            wrapper.eq(InspectionOrderItem::getCustomerId, customerId);
        }
        if (hasText(cabinetId)) {
            wrapper.eq(InspectionOrderItem::getCabinetId, cabinetId);
        }
        List<InspectionOrderItem> list = this.getBaseMapper().selectList(wrapper);
        if (list == null || list.isEmpty()) {
            return ResponseResult.notFound(null, "该工单暂无客户配电箱检查项");
        }
        return ResponseResult.ok(list);
    }

    @Override
    public ResponseResult<Boolean> hasOrderItem(InspectionOrderItemExistReqDTO in) {
        if (StringUtils.isBlank(in.getOrderId())) {
            return ResponseResult.parameterError(null, "工单ID不能为空");
        }
        LambdaQueryWrapper<InspectionOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InspectionOrderItem::getInspectionOrderId, in.getOrderId());
        if (hasText(in.getCustomerType())) {
            wrapper.eq(InspectionOrderItem::getCustomerType, CustomerType.of(in.getCustomerType()));
        }
        if (hasText(in.getCustomerId())) {
            wrapper.eq(InspectionOrderItem::getCustomerId, in.getCustomerId());
        }
        if (hasText(in.getRoomId())) {
            wrapper.eq(InspectionOrderItem::getRoomId, in.getRoomId());
        }
        if (hasText(in.getCabinetId())) {
            wrapper.eq(InspectionOrderItem::getCabinetId, in.getCabinetId());
        }
        return ResponseResult.ok(this.exists(wrapper));
    }

    @Override
    public ResponseResult<String> deleteByOrderId(String orderId) {
        if (StringUtils.isBlank(orderId)) {
            return ResponseResult.parameterError(null, "工单ID不能为空");
        }
        LambdaQueryWrapper<InspectionOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InspectionOrderItem::getInspectionOrderId, orderId);
        boolean removed = this.applicationContext.getBean(InspectionOrderItemService.class).remove(wrapper);
        if (removed) {
            eventPublisher.publishEvent(
                    InspectionOrderItemChangeEvent.updated(orderId, null)
            );
            return ResponseResult.ok("删除成功！");
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "删除失败，请稍后重试", null);
    }

    @Override
    public ResponseResult<String> deleteByCustomerId(String orderId, CustomerType customerType, String customerId) {
        if (StringUtils.isBlank(orderId)) {
            return ResponseResult.parameterError(null, "工单ID不能为空");
        }
        if (customerType == null) {
            return ResponseResult.parameterError(null, "客户类型不能为空");
        }
        if (StringUtils.isBlank(customerId)) {
            return ResponseResult.parameterError(null, "客户ID不能为空");
        }
        LambdaQueryWrapper<InspectionOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InspectionOrderItem::getInspectionOrderId, orderId)
                .eq(InspectionOrderItem::getCustomerType, customerType)
                .eq(InspectionOrderItem::getCustomerId, customerId);
        boolean removed = this.applicationContext.getBean(InspectionOrderItemService.class).remove(wrapper);
        if (removed) {
            eventPublisher.publishEvent(
                    InspectionOrderItemChangeEvent.updated(orderId, customerId)
            );
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "删除失败，请稍后重试", null);
    }

    @Override
    public ResponseResult<String> deleteByRoomId(String orderId, String roomId) {
        if (StringUtils.isBlank(orderId)) {
            return ResponseResult.parameterError(null, "工单ID不能为空");
        }
        if (StringUtils.isBlank(roomId)) {
            return ResponseResult.parameterError(null, "配电房ID不能为空");
        }
        LambdaQueryWrapper<InspectionOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InspectionOrderItem::getInspectionOrderId, orderId)
                .eq(InspectionOrderItem::getRoomId, roomId);
        boolean removed = this.applicationContext.getBean(InspectionOrderItemService.class).remove(wrapper);
        if (removed) {
            eventPublisher.publishEvent(
                    InspectionOrderItemChangeEvent.updated(orderId, null)
            );
            return ResponseResult.ok("删除成功！");
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "删除失败，请稍后重试", null);
    }

    @Override
    public ResponseResult<String> deleteByCabinetId(String orderId, String roomId, String cabinetId) {

        if (StringUtils.isBlank(orderId)) {
            return ResponseResult.parameterError(null, "工单ID不能为空");
        }
        if (StringUtils.isBlank(cabinetId)) {
            return ResponseResult.parameterError(null, "配电箱ID不能为空");
        }
        LambdaQueryWrapper<InspectionOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InspectionOrderItem::getInspectionOrderId, orderId)
                .eq(InspectionOrderItem::getRoomId, roomId)
                .eq(InspectionOrderItem::getCabinetId, cabinetId);
        boolean removed = this.applicationContext.getBean(InspectionOrderItemService.class).remove(wrapper);
        if (removed) {
            eventPublisher.publishEvent(
                    InspectionOrderItemChangeEvent.updated(orderId, null)
            );
            return ResponseResult.ok("删除成功！");
        }
        return ResponseResult.failure(ResponseCode.INTERNAL_SERVER_ERROR, "删除失败，请稍后重试", null);
    }

    //今日巡查异常项数
    @Override
    public ResponseResult<Long> countTodayExceptionByCustomerId(String orgId) {
        if (StringUtils.isBlank(orgId)) {
            return ResponseResult.parameterError(null, "客户ID不能为空");
        }

        LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
        LocalDateTime endOfDay = LocalDate.now().atTime(LocalTime.MAX); // 23:59:59.999999999

        LambdaQueryWrapper<InspectionOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(InspectionOrderItem::getCustomerId, orgId)
                .eq(InspectionOrderItem::getResultStatus, InspectionOrderItemResultStatus.ABNORMAL)
                .ge(InspectionOrderItem::getCreatedAt, startOfDay)
                .le(InspectionOrderItem::getCreatedAt, endOfDay);

        long count = this.baseMapper.selectCount(wrapper);
        return ResponseResult.ok(count);
    }
}